package com.trkj.service;

import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.trkj.dao.AttendanceDAO;
import com.trkj.dao.AttendanceparamDAO;
import com.trkj.dao.AttendancetypeDAO;
import com.trkj.dao.EmpDAO;
import com.trkj.dao.LoanlogDAO;
import com.trkj.dao.OverworkDAO;
import com.trkj.pojo.Attendance;
import com.trkj.pojo.Attendanceparam;
import com.trkj.pojo.Attendancetype;
import com.trkj.pojo.Emp;
import com.trkj.pojo.Overwork;
import com.trkj.utils.DataGrid;
import com.trkj.vo.AttendanceVo;
import com.trkj.vo.LoanEmpVo;

@Service
@Transactional
public class AttendanceService {
	@Autowired
	private AttendanceDAO attendanceDAO;
	@Autowired
	private EmpDAO empDAO;
	@Autowired
	AttendancetypeDAO attendancetypeDAO;
	@Autowired
	AttendanceparamDAO attendanceparamDAO;
	@Autowired
	LoanlogDAO loanlogDAO;
	@Autowired
	WorkFlowService workFlowService;
	@Autowired
	OverworkDAO overworkDAO;

	/**
	 * 添加一个签到的记录
	 * 
	 * @author skm
	 * @return author skm
	 */
	public Attendance sava_Attendance_Checkin(Emp emp) {
		try {
			Attendance attendance2 = new Attendance();
			Date date = new Date();
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd ");
			String nowdata = formatter.format(date);
			attendance2.setAttendanceDate(formatter.parse(nowdata));
			
			SimpleDateFormat formatter2 = new SimpleDateFormat("HH:mm:ss");//把date转换成hh:mm:ss格式
			String nowhms = formatter2.format(date.getTime());//转成字符串
			Time time = Time.valueOf(nowhms);//将string转成Time格式
			attendance2.setAttendanceOnworktime(time);//保存在签到的信息中
			//attendance2.setAttendanceOnworktime(new Time(date.getTime()));
			attendance2.setEmp(emp);
			// 找到设定上下班的时间
			Attendanceparam attp = attendanceparamDAO.findByAttparamState(true);
			Time time1 = attendance2.getAttendanceOnworktime();
			Time time2 = attp.getAttparamLate();
			Attendancetype attendancetype = null;
			if (time1.getTime() <= time2.getTime()) {// 判断两个时间的大小如果没迟到就返回正常班
				// 找到正常班的id
				attendancetype = attendancetypeDAO.findOne(1);
			}else if(time1.getTime() <= time2.getTime() && isOverWork(emp.getEmpId())){//判断是否加班,如果加班找到对应的上班类型
				attendancetype = attendancetypeDAO.findOne(5);
			} else {// 迟到
				attendancetype = attendancetypeDAO.findOne(3);
			}
			attendance2.setAttendancetype(attendancetype);
			return attendanceDAO.save(attendance2);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 查看今天是否签到，如果已经签到就返回一个签到的记录对象给当前用户
	 * 
	 * @param emp
	 * @return author skm
	 */
	public Attendance qiandao(Emp emp) {
		Date now = new Date();// 获取系统时间
		// 通过empid和今天的日期（attendance_date年月日）查询一个考勤记录对象，用于判断当前用户的签到信息
		Attendance attendance = attendanceDAO.findByEmpONday(emp.getEmpId(), new Time(now.getTime()));
		if (attendance != null) {// 代表已经上班
			return attendance;// 如果已经签到，则直接返回当前用户今天的考勤记录对象
		}
		// 如果今天该用还没签到，就给保存一个考勤记录对象，代指签到操作
		Attendance saveattendance = sava_Attendance_Checkin(emp);
		return saveattendance;// 最终返回保存的考勤记录对象
	}

	/**
	 * 签退
	 * 
	 * @param emp
	 * @return
	 * @author skm
	 */
	public Attendance qiantui(Emp emp) {
		Date now = new Date();// 获取系统时间
		Attendance attendance = attendanceDAO.findByEmpONday(emp.getEmpId(), new Time(now.getTime()));
		if (attendance != null) {
			// 找到上班的时间设定界限
			Attendanceparam attp = attendanceparamDAO.findByAttparamState(true);
			Attendancetype attendancetype = null;
			if (attendance.getAttendanceOffworktime() == null) {// 签了上班，还没签下班
				
				SimpleDateFormat formatter2 = new SimpleDateFormat("HH:mm:ss");//把date转换成hh:mm:ss格式
				String nowhms = formatter2.format(now.getTime());//转成字符串
				Time time = Time.valueOf(nowhms);//将string转成Time格式
				
				attendance.setAttendanceOffworktime(time);// 所以这里签的是下班
				Time time1 = attendance.getAttendanceOffworktime();// 找到签退的时间
				Time time2 = attp.getAttparamLeaveearly();// 找到签退的时间界限
				Time time3 = attendance.getAttendanceOnworktime();// 找到签到的时间
				Time time4 = attp.getAttparamLate();// 找到签到的时间界限
				if (time1.getTime() >= time2.getTime() && time3.getTime() >= time4.getTime()) {
					attendancetype = attendancetypeDAO.findOne(2);// 迟到
				} else if (time1.getTime() <= time2.getTime() && time3.getTime() <= time4.getTime()) {// 判断是否早退
					attendancetype = attendancetypeDAO.findOne(3);// 早退
				} else if (time1.getTime() <= time2.getTime() && time3.getTime() >= time4.getTime()) {// 判断迟到与早退
					attendancetype = attendancetypeDAO.findOne(4);// 迟到+早退
				} else {
					attendancetype = attendancetypeDAO.findOne(1);// 如果没有迟到和早退，则为正常上班
				}
				attendance.setAttendancetype(attendancetype);
				return attendance;
			}
		}
		return null;
	}

	/**
	 * 查看当前的签到的记录
	 * 
	 * @param emp
	 * @return
	 */
	public Attendance look_Attendance(Emp emp) {
		Date now = new Date();// 获取系统时间
		Attendance attendance = attendanceDAO.findByEmpONday(emp.getEmpId(), new Time(now.getTime()));
		if (attendance!=null) {
			return attendance;
		}
		return null;
	}
	
	
	/**
	 * 创建分页查询，个人考勤记录
	 * @param emp
	 * @param starttime
	 * @param endtime
	 * @param page
	 * @param rows
	 * @param sort
	 * @param order
	 * @return
	 */
	public DataGrid findOneAllCheckInfo(Emp emp,Date starttime, Date endtime, Integer page, Integer rows, String sort, String order) {
		Pageable pageable = new PageRequest(page-1, rows, new Sort(Sort.Direction.fromStringOrNull(order), sort));
		
		if(endtime==null) {
			Calendar cale = Calendar.getInstance();
			int month = cale.get(Calendar.MONTH) + 1;
			 // 获取当月第一天和最后一天  
	        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
	        // 获取前月的第一天  
	        cale = Calendar.getInstance();  
	        cale.add(Calendar.MONTH, 0);  
	        cale.set(Calendar.DAY_OF_MONTH, 1);  
	        try {
				starttime = format.parse(format.format(cale.getTime()));
		        Date date = new Date();
		        
		        endtime = format.parse(format.format(date));
			} catch (ParseException e) {
				e.printStackTrace();
			} 
		}
		Page<Attendance> pageSelect = pageSelect(starttime, endtime, pageable);
		//查询结果集合
		List<Attendance> attendances = pageSelect.getContent();
		//转为VO集合
		List<AttendanceVo> AttendanceVos = new ArrayList<>();
		//找到启用考勤参数
		Attendanceparam attp = attendanceparamDAO.findByAttparamState(true);
		for (Attendance attendance : attendances) {
			AttendanceVo attendanceVo = new AttendanceVo();
			attendanceVo.setAttendanceId(attendance.getAttendanceId());
			attendanceVo.setAttendanceDate(attendance.getAttendanceDate());
			attendanceVo.setAttendanceOffworktime(attendance.getAttendanceOffworktime()+"");
			attendanceVo.setAttendanceOnworktime(attendance.getAttendanceOnworktime()+"");
			attendanceVo.setAttypeId(attendance.getAttendancetype().getAttypeId());
			attendanceVo.setAttypeName(attendance.getAttendancetype().getAttypeName());
			attendanceVo.setEmpId(emp.getEmpId());
			attendanceVo.setEmpName(attendance.getEmp().getEmpName());
			
			//加入考勤参数
			attendanceVo.setAttparamId(attp.getAttparamId());
			attendanceVo.setAttparamLate(attp.getAttparamLate()+"");
			attendanceVo.setAttparamLeaveearly(attp.getAttparamLeaveearly()+"");
			attendanceVo.setAttparamYearday(attp.getAttparamYearday());
			AttendanceVos.add(attendanceVo);
		}
		return new DataGrid(pageSelect.getTotalElements(), AttendanceVos);
	}

	/**
	 * 创建分页查询
	 */
	private Page<Attendance> pageSelect(Date starttime, Date endtime, Pageable pageable) {
		 Page<Attendance> Attendances = attendanceDAO.findAll(new Specification<Attendance>() {
				
				@Override
				public Predicate toPredicate(Root<Attendance> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
					Predicate p2=null;
					List<Predicate> list = new ArrayList<Predicate>();
					if(starttime!=null) {
						p2 = cb.between(root.get("attendanceDate"), starttime, endtime);
						list.add(p2);
					} 
					Predicate[] p = new Predicate[list.size()];
		            return cb.and(list.toArray(p));
					
				}
			},pageable);
			return Attendances;
	}
	
	
	/**
	 * 个人借款信息
	 * @param empId
	 * @return
	 */
	@SuppressWarnings("null")
	public List<LoanEmpVo> oneloanlogInfo(Integer empId) {
		List<Object[]> list=null;
		list = loanlogDAO.findLoanlogInfo(empId);
		List<LoanEmpVo> listvo = new ArrayList<>();
		for (Object[] objects : list) {
			LoanEmpVo vo = new LoanEmpVo();
			vo.setEmpId(objects[1]+"");
			vo.setLoanlogTime(objects[2]+"");
			vo.setLoanlogLastmoney(objects[3]+"");
			vo.setLoanlogThismoney(objects[4]+"");
			vo.setLoanlogFiow(objects[5]+"");
			vo.setLoanlogNote(objects[6]+"");
			vo.setEmpName(objects[7]+"");
			listvo.add(vo);
		}
		return listvo;
	}
	
	
	
	
	/**
	 * 判断是否在加班
	 * @param empId 
	 * @param processDefinitionKey
	 * @return
	 */
	public boolean isOverWork(Integer empId ) {//
		Integer processId = workFlowService.getRecentlyProcessFinished(empId, "overwork_act");
		if (processId!=null) {
			Overwork overwork = overworkDAO.findOne(processId);
			Date starttime = overwork.getOverworkStarttime();//加班的开始时间
			Date endtime = overwork.getOverworkEndtime();//加班的结束时间
			Date now = new Date();//调用该方法的时间
			//判断是否加班true：代表加班状态，false：代表不是加班
			if(now.getTime()>starttime.getTime()) {
				return false;
			}else if(starttime.getTime()>now.getTime() && endtime.getTime()>starttime.getTime()){
				return true;
			}
		}
		return false;
	}
	

}
